﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using Microsoft.Practices.Unity;
using MiniStock.Entities.Common;
using System.ComponentModel.DataAnnotations;

namespace MiniStock.Entities.Stock
{
    [DataContract(IsReference=true)]
    public class Product: EntityBase
    {
        [DataMember]
        public string ProductNumber { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Description { get; set; }
        [ForeignKey("Manufacturer")][DataMember]
        public Guid? ManufacturerId { get; set; }
        [DataMember]
        public List<OrderItem> OrderItems { get; set; }   
        [DataMember][ForeignKey("ManufacturerId")]
        public Customer Manufacturer { get; set; }

        public Product()
        {
            OrderItems = new List<OrderItem>();
        }

        public override void CopyFrom(EntityBase source, int depthLimit=-1)
        {
            var product = (Product) source;

            base.CopyFrom(source, depthLimit);
            this.Name = product.Name;
            this.ProductNumber = product.ProductNumber;
            this.Description = product.Description;
            this.ManufacturerId = product.ManufacturerId;

            if (depthLimit != 0)
            {
                this.OrderItems = product.OrderItems.Select(i =>
                                                                {
                                                                    var j = new OrderItem();
                                                                    j.CopyFrom(i, depthLimit - 1);
                                                                    return j;
                                                                }).ToList();
            } else
            {
                this.OrderItems = null;
            }
        }

        #region Validators

        public static class Validator
        {
            public static void ProductNameMandatory(Product current, IEntityProvider provider, string newName)
            {
                if (string.IsNullOrEmpty(newName))
                    throw new ValidationException("Product name must be specified");
            }

            public static void ProductNameUnique(Product current, IEntityProvider provider, string newName)
            {
                if (provider.All<Product>().Exists(i => i.Name == newName && (current == null || i.Id != current.Id)))
                {
                    throw new ValidationException("Product name must be unique");
                }
            }

            public static void ProductNumberMandatory(Product current, IEntityProvider provider, string newProductNumber)
            {
                if (string.IsNullOrEmpty(newProductNumber))
                    throw new ValidationException("Product number must be specified");
            }

            public static void ProductNumberUnique(Product current, IEntityProvider provider, string newProductNumber)
            {
                if (provider.All<Product>().Exists(i => i.ProductNumber == newProductNumber && (current == null || i.Id != current.Id)))
                {
                    throw new ValidationException("Product name must be unique");
                }
            }
        }

        #endregion
    }
}
